package com.prestamomo.vil.ppa.pmvilpage;

import android.Manifest;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.text.TextUtils;
import android.util.Size;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraControl;
import androidx.camera.core.CameraInfo;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.FocusMeteringAction;
import androidx.camera.core.FocusMeteringResult;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.MeteringPoint;
import androidx.camera.core.MeteringPointFactory;
import androidx.camera.core.Preview;
import androidx.camera.core.SurfaceOrientedMeteringPointFactory;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.alibaba.fastjson.JSONObject;
import com.bumptech.glide.Glide;
import com.google.common.util.concurrent.ListenableFuture;
import com.prestamomo.vil.ppa.R;
import com.prestamomo.vil.ppa.pmvilnet.PmvilAjustinfse;
import com.prestamomo.vil.ppa.pmvilpage.pmcamera.PmvilFileUtil;
import com.prestamomo.vil.ppa.pmvilpage.pmcamera.PmvilParamBean;
import com.prestamomo.vil.ppa.pmvilpage.pmcamera.PmvilTools;
import com.prestamomo.vil.ppa.pmvilpage.pmrot.PmvilAtyRoot;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

public class PmvilCameraVy extends PmvilAtyRoot implements View.OnClickListener {
    public final static int PMVYREQUEST_CODE = 0X13;

    private ProcessCameraProvider camerapmvyProvider;

    private ImageCapture imagePmvyCapture;

    private CameraInfo mCameraPmvyInfo;

    private CameraControl mCameraPmvyControl;

    private CameraSelector cameraPmvySelector;

    private PreviewView cameraPmvyView;
    private LinearLayout cameraPmvyContainer;
    private LinearLayout containerPmvyView;
    private ImageView cropPmvyView;
    private ImageView closePmvyView;
    private ImageView cameraPmvyTake;
    private ImageView takePmvySuccess;
    private ImageView takePmvyCancel;
    private RelativeLayout previewPmvyPicture;
    private ImageView imgPmvyPicture;
    private LinearLayout cameraPmvyOption;
    private LinearLayout cameraPmvyTakeOption;
    private TextView touchPmvyText;

    private Bitmap photoPmvyBitmap = null;

    private boolean enablePmvyTorchStatus = false;
    private PmvilParamBean paramPmvyBean;

    @Override
    protected int getPmvilLayoutId() {
        String planPmvyString = getIntent().getStringExtra("pmvil_options");
        paramPmvyBean = JSONObject.parseObject(planPmvyString, PmvilParamBean.class);
        if (paramPmvyBean.getPmvilLandscape()) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            sendAdjPmvilEvent(PmvilAjustinfse.pmvil_kjhwflwge);
            sendAdjPmvilEvent(PmvilAjustinfse.pmvil_kjhwflwge_0);
        }
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        return R.layout.camera_pmvil_ly;
    }



    @Override
    protected void showPmvilUi() {

        cameraPmvyContainer = findViewById(R.id.camera_pmly_container);
        containerPmvyView = findViewById(R.id.camera_crop_container);
        cropPmvyView = findViewById(R.id.camera_pmly_crop);
        cameraPmvyView = findViewById(R.id.camera_pmly_view);
        closePmvyView = findViewById(R.id.camera_pmly_close);
        cameraPmvyTake = findViewById(R.id.camera_pmly_take);
        cameraPmvyOption = findViewById(R.id.camera_pmly_option);
        cameraPmvyTakeOption = findViewById(R.id.camera_pmly_take_option);
        takePmvySuccess = findViewById(R.id.take_pmly_success);
        takePmvyCancel = findViewById(R.id.take_pmly_cancel);
        previewPmvyPicture = findViewById(R.id.preview_pmly_picture);
        imgPmvyPicture = findViewById(R.id.img_pmly_picture);
        touchPmvyText = findViewById(R.id.touch_pmly_text);
        cameraPmvyView.setOnClickListener(this);
        closePmvyView.setOnClickListener(this);
        cameraPmvyTake.setOnClickListener(this);
        takePmvySuccess.setOnClickListener(this);
        takePmvyCancel.setOnClickListener(this);
        takePmvySuccess.setOnClickListener(this);
        View backPmvyColor1 = findViewById(R.id.back_pmly_Color1);
        View backPmvyColor2 = findViewById(R.id.back_pmly_Color2);
        View backPmvyColor3 = findViewById(R.id.back_pmly_Color3);

        if (!TextUtils.isEmpty(paramPmvyBean.getPmvilbackColor())) {
            backPmvyColor1.setBackgroundColor(Color.parseColor(paramPmvyBean.getPmvilbackColor()));
            backPmvyColor2.setBackgroundColor(Color.parseColor(paramPmvyBean.getPmvilbackColor()));
            backPmvyColor3.setBackgroundColor(Color.parseColor(paramPmvyBean.getPmvilbackColor()));
            touchPmvyText.setBackgroundColor(Color.parseColor(paramPmvyBean.getPmvilbackColor()));
        }


        float screenPmvyMinSize = Math.min(getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
        //lauch
        float pmvyHeight = (int) (screenPmvyMinSize * 0.75);
        float pmvyWidth = (int) (pmvyHeight * 75.0f / 47.0f);
        LinearLayout.LayoutParams containerPmvyParams = new LinearLayout.LayoutParams((int) pmvyWidth, ViewGroup.LayoutParams.MATCH_PARENT);
        LinearLayout.LayoutParams cropPmvyParams = new LinearLayout.LayoutParams((int) pmvyWidth, (int) pmvyHeight);

        //pathis
        if (!paramPmvyBean.getPmvilLandscape()) {
            pmvyWidth = (int) (screenPmvyMinSize * 0.9);
            pmvyHeight = (int) (pmvyWidth * 47.0f / 35.0f);
            containerPmvyParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) pmvyHeight);
            cropPmvyParams = new LinearLayout.LayoutParams((int) pmvyWidth, (int) pmvyHeight);
        }

        containerPmvyView.setLayoutParams(containerPmvyParams);
        cropPmvyView.setLayoutParams(cropPmvyParams);
        if (!TextUtils.isEmpty(paramPmvyBean.getPmvilbackgroundImage())) {
            Bitmap backPmvyGroundImage = getImagePmvyFromAssetsFile(paramPmvyBean.getPmvilbackgroundImage());
            if (backPmvyGroundImage != null) {
                cropPmvyView.setImageBitmap(backPmvyGroundImage);
            }
        }


        if (paramPmvyBean.getPmvilCamerType()!=0) {
            touchPmvyText.setText(paramPmvyBean.getPmviltext());
        }else {
            touchPmvyText.setText("");
        }

        String[] permisPmvysions = new String[]{Manifest.permission.CAMERA};

        List<String> mPermisPmvysionList = new ArrayList<>();

        for (int i = 0; i < permisPmvysions.length; i++) {
            if (ContextCompat.checkSelfPermission(this, permisPmvysions[i]) != PackageManager.PERMISSION_GRANTED) {
                mPermisPmvysionList.add(permisPmvysions[i]);
            }
        }

        if (mPermisPmvysionList.size() > 0) {
            ActivityCompat.requestPermissions(this, permisPmvysions, 1);
        } else {
                startPmvyCamera();
        }

    }


    /**
     * @param filePmvyName
     * @return
     */
    private Bitmap getImagePmvyFromAssetsFile(String filePmvyName) {
        Bitmap imagePmvy = null;
        AssetManager amPmvy = getResources().getAssets();
        try {
            InputStream isPmvy = amPmvy.open(filePmvyName);
            imagePmvy = BitmapFactory.decodeStream(isPmvy);
            isPmvy.close();
        } catch (IOException e) {
        }

        return imagePmvy;
    }

    @Override
    protected void clickePmvil() {

    }

    @Override
    protected void loadPmvilData() {

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (camerapmvyProvider != null) {
            camerapmvyProvider.unbindAll();
            camerapmvyProvider = null;
        }
    }



    /**
     * start camera
     */
    private void startPmvyCamera() {
        ListenableFuture<ProcessCameraProvider> cameraPmvyProviderFuture = ProcessCameraProvider.getInstance(this);
        cameraPmvyProviderFuture.addListener(new Runnable() {
            @Override
            public void run() {
                try {
                    camerapmvyProvider = cameraPmvyProviderFuture.get();
                    bindPmvilPreview(camerapmvyProvider);
                } catch (ExecutionException | InterruptedException e) {
//                    e.printStackTrace();
                }
            }
        }, ContextCompat.getMainExecutor(this));
    }

    /**
     * @return
     */
    int heightPmvyCamera, widthPmvyCamera;
    private Size getPmvySize() {

        heightPmvyCamera = Math.min(cameraPmvyView.getWidth(), cameraPmvyView.getHeight());
        widthPmvyCamera = Math.max(cameraPmvyView.getWidth(), cameraPmvyView.getHeight());
        if (!paramPmvyBean.getPmvilLandscape()) {
            heightPmvyCamera = Math.max(cameraPmvyView.getWidth(), cameraPmvyView.getHeight());
            widthPmvyCamera = Math.min(cameraPmvyView.getWidth(), cameraPmvyView.getHeight());
        }
        Size screenPmvyAspectRatio = new Size(widthPmvyCamera, heightPmvyCamera);
        return screenPmvyAspectRatio;
    }

    /**
     * @param cameraPmvilProvider
     */
    public void bindPmvilPreview(@NonNull ProcessCameraProvider cameraPmvilProvider) {
        cameraPmvilProvider.unbindAll();

        cameraPmvyView.post(new Runnable() {
            @Override
            public void run() {
                Size pmvilSize = getPmvySize();
                int rotation = paramPmvyBean.getPmvilLandscape() ? Surface.ROTATION_90 : Surface.ROTATION_0;
                imagePmvyCapture = new ImageCapture.Builder()
                        .setTargetResolution(pmvilSize)
                        .setTargetRotation(rotation)
                        .build();

                Preview pmvilPreview = new Preview.Builder()
                        .setTargetResolution(pmvilSize)
                        .setTargetRotation(rotation)
                        .build();

                cameraPmvySelector = new CameraSelector.Builder()
                        .requireLensFacing(paramPmvyBean.getPmvilCamerType()==0?CameraSelector.LENS_FACING_FRONT:CameraSelector.LENS_FACING_BACK)
                        .build();

                try {
                    Camera pmvilCamera = cameraPmvilProvider.bindToLifecycle(PmvilCameraVy.this, cameraPmvySelector, pmvilPreview, imagePmvyCapture);
                    pmvilPreview.setSurfaceProvider(cameraPmvyView.getSurfaceProvider());
                    mCameraPmvyInfo = pmvilCamera.getCameraInfo();
                    mCameraPmvyControl = pmvilCamera.getCameraControl();
                } catch (Exception pmvilExc) {
                    pmvilExc.printStackTrace();
                }

            }
        });

    }

    /**
     * @param pmvilx
     * @param pmvily
     */
    private void autoPmvilFocus(int pmvilx, int pmvily) {
        MeteringPointFactory pmvilfactory = new SurfaceOrientedMeteringPointFactory(pmvilx, pmvily);
        MeteringPoint poipmvilnt = pmvilfactory.createPoint(pmvilx, pmvily);
        FocusMeteringAction focuPmvilAction = new FocusMeteringAction.Builder(poipmvilnt, FocusMeteringAction.FLAG_AF)
                .setAutoCancelDuration(3, TimeUnit.SECONDS)
                .build();
        ListenableFuture<FocusMeteringResult> futpmvilure = mCameraPmvyControl.startFocusAndMetering(focuPmvilAction);
        futpmvilure.addListener(() -> {
            try {
                FocusMeteringResult result = futpmvilure.get();
                if (result.isFocusSuccessful()) {
                } else {
                }
            } catch (Exception e) {
                e.printStackTrace();

            }
        }, ContextCompat.getMainExecutor(this));
    }

    @Override
    public void onClick(View v) {
        int pmvilId = v.getId();
        if (pmvilId == R.id.camera_pmly_view) {
            if(paramPmvyBean.getPmvilCamerType()!=0){
                int[] outLocation = PmvilTools.getViewPmvilLocal(cropPmvyView);
                autoPmvilFocus(outLocation[0] + (cropPmvyView.getMeasuredWidth()) / 2, outLocation[1] + (cropPmvyView.getMeasuredHeight()) / 2);
            }
        } else if (pmvilId == R.id.camera_pmly_close) {
            finish();
        } else if (pmvilId == R.id.camera_pmly_take) {
            takePmvilPhoto();
        } else if (pmvilId == R.id.take_pmly_cancel) {
            previewPmvyPicture.setVisibility(View.GONE);
            cameraPmvyOption.setVisibility(View.VISIBLE);
            cameraPmvyTakeOption.setVisibility(View.GONE);
        } else if (pmvilId == R.id.take_pmly_success) {
            cutPmvilPhoto();
        }
    }

    /**
     * cut img
     */
    public void cutPmvilPhoto() {
        if (photoPmvyBitmap == null) {
            return;
        }
        float pmvilleft = ((float) containerPmvyView.getLeft() - (float) cameraPmvyView.getLeft()) / (float) cameraPmvyView.getWidth();
        float pmviltop = (float) cropPmvyView.getTop() / (float) cameraPmvyView.getHeight();
        float pmvilright = (float) containerPmvyView.getRight() / (float) cameraPmvyView.getWidth();
        float pmvilbottom = (float) cropPmvyView.getBottom() / (float) cameraPmvyView.getHeight();

        if (!paramPmvyBean.getPmvilLandscape()) {
            pmvilleft = ((float) cropPmvyView.getLeft() - (float) cameraPmvyView.getLeft()) / (float) cameraPmvyView.getWidth();
            pmviltop = (float) containerPmvyView.getTop() / (float) cameraPmvyView.getHeight();
            pmvilright = (float) cropPmvyView.getRight() / (float) cameraPmvyView.getWidth();
            pmvilbottom = (float) containerPmvyView.getBottom() / (float) cameraPmvyView.getHeight();
        }

        //carput img and save img
        Bitmap resPmvilBitmap = Bitmap.createBitmap(photoPmvyBitmap,
                (int) (pmvilleft * (float) photoPmvyBitmap.getWidth()),
                (int) (pmviltop * (float) photoPmvyBitmap.getHeight()),
                (int) ((pmvilright - pmvilleft) * (float) photoPmvyBitmap.getWidth()),
                (int) ((pmvilbottom - pmviltop) * (float) photoPmvyBitmap.getHeight()));

        PmvilFileUtil.savePmvilBitmap(this, resPmvilBitmap);
        if (!resPmvilBitmap.isRecycled()) {
            resPmvilBitmap.recycle();
        }

        Intent pmvilIntent = new Intent();
        if (paramPmvyBean.getPmvilfullSrc()) {
            pmvilIntent.putExtra("pmvil_result", "file://" + PmvilFileUtil.getPmvil_imgPath());
        } else {
            pmvilIntent.putExtra("pmvil_result", PmvilFileUtil.getPmvil_imgPath());
        }
        setResult(1000, pmvilIntent);
        finish();
    }


    /**
     * permiss result message
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        boolean hasPmvilPermissionDismiss = false;//有权限没有通过
        if (1 == requestCode) {
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] == -1) {
                    hasPmvilPermissionDismiss = true;
                }
            }
            if (!hasPmvilPermissionDismiss) {
                startPmvyCamera();
            }
        }

    }


    private void takePmvilPhoto() {
        if (imagePmvyCapture == null) {
            return;
        }
        String photoPmvilFile = System.currentTimeMillis() + "pmvil_cameraX.jpg";
        File pmvilFile = new File(this.getExternalCacheDir(), photoPmvilFile);
        ImageCapture.OutputFileOptions outputOptions = new ImageCapture.OutputFileOptions.Builder(pmvilFile).build();
        imagePmvyCapture.takePicture(outputOptions, ContextCompat.getMainExecutor(PmvilCameraVy.this), new ImageCapture.OnImageSavedCallback() {
            @Override
            public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                previewPmvyPicture.setVisibility(View.VISIBLE);
                cameraPmvyOption.setVisibility(View.GONE);
                cameraPmvyTakeOption.setVisibility(View.VISIBLE);
                //NOVA9 phone
                if (android.os.Build.MODEL == "NAM-AL00") {
                    Bitmap bitPmvilmap = BitmapFactory.decodeFile(pmvilFile.getAbsolutePath());
                    Matrix matrPmvliix = new Matrix();
                    int degPmvilree = 0;
                    if (!paramPmvyBean.getPmvilLandscape()) {
                        degPmvilree = 90;
                    }
                    matrPmvliix.postRotate(degPmvilree);
                    photoPmvyBitmap = Bitmap.createBitmap(bitPmvilmap, 0, 0, bitPmvilmap.getWidth(), bitPmvilmap.getHeight(), matrPmvliix, true);

                } else {
                    photoPmvyBitmap = PmvilTools.bitmapPmvilClip(pmvilFile.getAbsolutePath());
                }
                Glide.with(PmvilCameraVy.this).asBitmap().load(photoPmvyBitmap).into(imgPmvyPicture);
                pmvilFile.delete();
            }

            @Override
            public void onError(@NonNull ImageCaptureException exception) {
                exception.printStackTrace();
            }
        });
    }
}
